[PATCH] Kerberor4 client separation
Alexey Mahotkin <[email protected]>
| Newsgroups | gmane.comp.version-control.cvs.bugs |
|---|---|
| Message-ID | <[email protected]> |
I don't have any change to check that this patch works, but the nature of it is very simple and I guess that it could be fixed. AFAICT, Kerberos 4 is pretty obsolete these days, so maybe it's not a big deal. Anyway, it's the last system-specific part of client.c, which is now 5144 lines instead of ~6000 it was. Derek, if you're going to apply this, I could regenerate it any time you wish, if/after you apply some/all of previous patches. My current "series" file is like this: socket-client.patch socket-client-fix.patch gssapi-client.patch rsh-client.patch log-buffer.patch rsh-client-fix.patch from-to-server-p.patch local-from-to-server.patch via_buffer.patch kerberos-client.patch (the removal of includeopt is not here, but it should give only a single trivial reject). 2003-05-02 Alexey Mahotkin <[email protected]> Move Kerberos4 client stuff to kerberos4-client.[ch] init_sockaddr() is used almost universally in clients, so move its declaration to socket-client.h; rename HAVE_KERBEROS to HAVE_KERBEROS4, to emphasize that we're dealing with old Kerberos (K5 works via GSSAPI); rename start_tcp_server() to start_kerberos4_server(); Debian Woody has Kerberos 4 in -lkrb4 instead of -lkrb, so check for that; config.h.in | 2 configure.in | 5 +- src/Makefile.am | 3 - src/client.c | 116 ++++--------------------------------------------- src/client.h | 8 +-- src/kerberos4-client.c | 102 +++++++++++++++++++++++++++++++++++++++++++ src/kerberos4-client.h | 21 ++++++++ src/main.c | 8 +-- src/root.c | 2 src/server.c | 20 ++++---- src/socket-client.h | 8 ++- 11 files changed, 167 insertions(+), 128 deletions(-) --- ccvs/src/client.c~kerberos-client Fri May 2 14:23:47 2003 +++ ccvs-alexm/src/client.c Fri May 2 15:06:43 2003 @@ -30,24 +30,10 @@ #include "socket-client.h" #include "gssapi-client.h" +#include "kerberos4-client.h" #include "rsh-client.h" -# if HAVE_KERBEROS - -# include <krb.h> - -extern char *krb_realmofhost (); -# ifndef HAVE_KRB_GET_ERR_TEXT -# define krb_get_err_text(status) krb_err_txt[status] -# endif /* HAVE_KRB_GET_ERR_TEXT */ - -/* Information we need if we are going to use Kerberos encryption. */ -static C_Block kblock; -static Key_schedule sched; - -# endif /* HAVE_KERBEROS */ - static void add_prune_candidate PROTO((char *)); /* All the commands. */ @@ -3271,11 +3257,8 @@ supported_request (name) -#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) -static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *, - unsigned int)); - -static struct hostent * +#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS4) || defined (HAVE_GSSAPI) +struct hostent * init_sockaddr (name, hostname, port) struct sockaddr_in *name; char *hostname; @@ -3372,10 +3355,10 @@ get_cvs_port_number (root) # if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) return get_port_number ("CVS_CLIENT_PORT", "cvspserver", CVS_AUTH_PORT); # endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */ -# ifdef HAVE_KERBEROS +# ifdef HAVE_KERBEROS4 case kserver_method: return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT); -# endif /* HAVE_KERBEROS */ +# endif /* HAVE_KERBEROS4 */ default: error(1, EINVAL, "internal error: get_cvs_port_number called for invalid connection method (%s)", method_names[root->method]); @@ -3444,7 +3427,7 @@ make_bufs_from_fds (tofd, fromfd, child_ (BUFMEMERRPROC) NULL); } } -#endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */ +#endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS4) || defined(HAVE_GSSAPI) */ @@ -3731,83 +3714,6 @@ connect_to_forked_server (to_server_p, f -#ifdef HAVE_KERBEROS -/* This function has not been changed to deal with NO_SOCKET_TO_FD - (i.e., systems on which sockets cannot be converted to file - descriptors). The first person to try building a kerberos client - on such a system (OS/2, Windows 95, and maybe others) will have to - take care of this. */ -void -start_tcp_server (root, to_server_p, from_server_p) - cvsroot_t *root; - struct buffer **to_server_p; - struct buffer **from_server_p; -{ - int s; - const char *portenv; - int port; - struct hostent *hp; - struct sockaddr_in sin; - char *hname; - - s = socket (AF_INET, SOCK_STREAM, 0); - if (s < 0) - error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - - port = get_cvs_port_number (root); - - hp = init_sockaddr (&sin, root->hostname, port); - - hname = xmalloc (strlen (hp->h_name) + 1); - strcpy (hname, hp->h_name); - - TRACE ( 1, "Connecting to %s(%s):%d", - root->hostname, - inet_ntoa (sin.sin_addr), - port ); - - if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0) - error (1, 0, "connect to %s(%s):%d failed: %s", - root->hostname, - inet_ntoa (sin.sin_addr), - port, SOCK_STRERROR (SOCK_ERRNO)); - - { - const char *realm; - struct sockaddr_in laddr; - int laddrlen; - KTEXT_ST ticket; - MSG_DAT msg_data; - CREDENTIALS cred; - int status; - - realm = krb_realmofhost (hname); - - laddrlen = sizeof (laddr); - if (getsockname (s, (struct sockaddr *) &laddr, &laddrlen) < 0) - error (1, 0, "getsockname failed: %s", SOCK_STRERROR (SOCK_ERRNO)); - - /* We don't care about the checksum, and pass it as zero. */ - status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd", - hname, realm, (unsigned long) 0, &msg_data, - &cred, sched, &laddr, &sin, "KCVSV1.0"); - if (status != KSUCCESS) - error (1, 0, "kerberos authentication failed: %s", - krb_get_err_text (status)); - memcpy (kblock, cred.session, sizeof (C_Block)); - } - - close_on_exec (s); - - free (hname); - - /* Give caller the values it wants. */ - make_bufs_from_fds (s, s, 0, to_server_p, from_server_p, 1); -} - -#endif /* HAVE_KERBEROS */ - - static int send_variable_proc PROTO ((Node *, void *)); static int @@ -3853,11 +3759,11 @@ start_server () break; #endif /* AUTH_CLIENT_SUPPORT */ -#if HAVE_KERBEROS +#if HAVE_KERBEROS4 case kserver_method: - start_tcp_server (current_parsed_root, &global_to_server, &global_from_server); + start_kerberos4_server (current_parsed_root, &global_to_server, &global_from_server); break; -#endif /* HAVE_KERBEROS */ +#endif /* HAVE_KERBEROS4 */ #ifdef HAVE_GSSAPI case gserver_method: @@ -4104,7 +4010,7 @@ start_server () we want to encrypt the compressed stream. If we can't turn on encryption, bomb out; don't let the user think the data is being encrypted when it is not. */ -#ifdef HAVE_KERBEROS +#ifdef HAVE_KERBEROS4 if (current_parsed_root->method == kserver_method) { if (! supported_request ("Kerberos-encrypt")) @@ -4118,7 +4024,7 @@ start_server () (BUFMEMERRPROC) NULL); } else -#endif /* HAVE_KERBEROS */ +#endif /* HAVE_KERBEROS4 */ #ifdef HAVE_GSSAPI if (current_parsed_root->method == gserver_method) { --- ccvs/src/client.h~kerberos-client Fri May 2 14:23:56 2003 +++ ccvs-alexm/src/client.h Fri May 2 15:03:08 2003 @@ -29,13 +29,13 @@ extern int cvsauthenticate; # ifdef ENCRYPTION -# ifdef HAVE_KERBEROS +# ifdef HAVE_KERBEROS4 /* We can't declare the arguments without including krb.h, and I don't want to do that in every file. */ extern struct buffer *krb_encrypt_buffer_initialize (); -# endif /* HAVE_KERBEROS */ +# endif /* HAVE_KERBEROS4 */ # endif /* ENCRYPTION */ @@ -64,11 +64,11 @@ void connect_to_pserver PROTO ((cvsroot_ # endif /* CVS_AUTH_PORT */ # endif /* (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */ -# if HAVE_KERBEROS +# if HAVE_KERBEROS4 # ifndef CVS_PORT # define CVS_PORT 1999 # endif -# endif /* HAVE_KERBEROS */ +# endif /* HAVE_KERBEROS4 */ /* Talking to the server. */ void send_to_server PROTO((char *str, size_t len)); --- /dev/null Wed Jan 1 02:48:46 2003 +++ ccvs-alexm/src/kerberos4-client.c Fri May 2 15:06:58 2003 @@ -0,0 +1,102 @@ +/* CVS Kerberos4 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 "socket-client.h" + +# include <krb.h> + +extern char *krb_realmofhost (); +# ifndef HAVE_KRB_GET_ERR_TEXT +# define krb_get_err_text(status) krb_err_txt[status] +# endif /* HAVE_KRB_GET_ERR_TEXT */ + +/* Information we need if we are going to use Kerberos encryption. */ +static C_Block kblock; +static Key_schedule sched; + + +/* This function has not been changed to deal with NO_SOCKET_TO_FD + (i.e., systems on which sockets cannot be converted to file + descriptors). The first person to try building a kerberos client + on such a system (OS/2, Windows 95, and maybe others) will have to + take care of this. */ +void +start_kerberos4_server (root, to_server_p, from_server_p) + cvsroot_t *root; + struct buffer **to_server_p; + struct buffer **from_server_p; +{ + int s; + int port; + struct hostent *hp; + struct sockaddr_in sin; + char *hname; + + s = socket (AF_INET, SOCK_STREAM, 0); + if (s < 0) + error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); + + port = get_cvs_port_number (root); + + hp = init_sockaddr (&sin, root->hostname, port); + + hname = xmalloc (strlen (hp->h_name) + 1); + strcpy (hname, hp->h_name); + + TRACE ( 1, "Connecting to %s(%s):%d", + root->hostname, + inet_ntoa (sin.sin_addr), + port ); + + if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0) + error (1, 0, "connect to %s(%s):%d failed: %s", + root->hostname, + inet_ntoa (sin.sin_addr), + port, SOCK_STRERROR (SOCK_ERRNO)); + + { + const char *realm; + struct sockaddr_in laddr; + int laddrlen; + KTEXT_ST ticket; + MSG_DAT msg_data; + CREDENTIALS cred; + int status; + + realm = krb_realmofhost (hname); + + laddrlen = sizeof (laddr); + if (getsockname (s, (struct sockaddr *) &laddr, &laddrlen) < 0) + error (1, 0, "getsockname failed: %s", SOCK_STRERROR (SOCK_ERRNO)); + + /* We don't care about the checksum, and pass it as zero. */ + status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd", + hname, realm, (unsigned long) 0, &msg_data, + &cred, sched, &laddr, &sin, "KCVSV1.0"); + if (status != KSUCCESS) + error (1, 0, "kerberos authentication failed: %s", + krb_get_err_text (status)); + memcpy (kblock, cred.session, sizeof (C_Block)); + } + + close_on_exec (s); + + free (hname); + + /* Give caller the values it wants. */ + make_bufs_from_fds (s, s, 0, to_server_p, from_server_p, 1); +} + --- /dev/null Wed Jan 1 02:48:46 2003 +++ ccvs-alexm/src/kerberos4-client.h Fri May 2 15:07:06 2003 @@ -0,0 +1,21 @@ +/* CVS Kerberos4 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 KERBEROS4_CLIENT_H__ +#define KERBEROS4_CLIENT_H__ + +extern void start_kerberos4_server PROTO((cvsroot_t *root, + struct buffer **to_server_p, struct buffer **from_server_p)); + +#endif + --- ccvs/src/Makefile.am~kerberos-client Fri May 2 14:24:08 2003 +++ ccvs-alexm/src/Makefile.am Fri May 2 14:58:11 2003 @@ -100,7 +100,8 @@ cvs_SOURCES = \ update.h \ watch.h -EXTRA_cvs_SOURCES = gssapi-client.c gssapi-client.h +EXTRA_cvs_SOURCES = gssapi-client.c gssapi-client.h \ + kerberos4-client.c kerberos4-client.h cvs_DEPENDENCIES = @client_objects@ cvs_LDADD = @client_objects@ \ --- ccvs/configure.in~kerberos-client Fri May 2 14:27:32 2003 +++ ccvs-alexm/configure.in Fri May 2 15:01:28 2003 @@ -383,11 +383,13 @@ if test -n "$krb_h"; then LDFLAGS=$hold_ldflags else AC_CHECK_LIB(krb,printf,[krb_lib=yes krb_libdir=]) + AC_CHECK_LIB(krb4, printf, [krb_lib=yes krb_libdir=]) AC_CHECK_FUNC(krb_recvauth,[krb_lib=yes krb_libdir=]) fi if test -n "$krb_lib"; then - AC_DEFINE([HAVE_KERBEROS], 1, + AC_DEFINE([HAVE_KERBEROS4], 1, [Define if you have MIT Kerberos version 4 available.]) + client_objects="$client_objects kerberos4-client.o" test -n "${krb_libdir}" && LIBS="${LIBS} -L${krb_libdir}" # Put -L${krb_libdir} in LDFLAGS temporarily so that it appears before # -ldes in the command line. Don't do it permanently so that we honor @@ -396,6 +398,7 @@ if test -n "$krb_h"; then test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}" AC_CHECK_LIB(des,printf,[LIBS="${LIBS} -ldes"]) AC_CHECK_LIB(krb,krb_recvauth) + AC_CHECK_LIB(krb4,krb_recvauth) LDFLAGS=$hold_ldflags if test -n "$krb_incdir"; then includeopt="${includeopt} -I$krb_incdir" --- ccvs/src/socket-client.h~kerberos-client Fri May 2 14:49:47 2003 +++ ccvs-alexm/src/socket-client.h Fri May 2 15:04:03 2003 @@ -18,7 +18,7 @@ struct buffer *socket_buffer_initialize PROTO ((int, int, void (*) (struct buffer *))); -# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR) +# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS4) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR) # ifdef HAVE_WINSOCK_H # include <winsock.h> # else /* No winsock.h */ @@ -28,6 +28,12 @@ struct buffer *socket_buffer_initialize # include <netdb.h> # endif /* No winsock.h */ # endif + +#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS4) || defined (HAVE_GSSAPI) +struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *, + unsigned int)); + +#endif /* If SOCK_ERRNO is defined, then send()/recv() and other socket calls do not set errno, but that this macro should be used to obtain an --- ccvs/config.h.in~kerberos-client Fri May 2 15:01:52 2003 +++ ccvs-alexm/config.h.in Fri May 2 15:04:32 2003 @@ -197,7 +197,7 @@ #undef HAVE_IO_H /* Define if you have MIT Kerberos version 4 available. */ -#undef HAVE_KERBEROS +#undef HAVE_KERBEROS4 /* Define to 1 if you have the <krb5.h> header file. */ #undef HAVE_KRB5_H --- ccvs/src/server.c~kerberos-client Fri May 2 15:02:13 2003 +++ ccvs-alexm/src/server.c Fri May 2 15:15:46 2003 @@ -50,7 +50,7 @@ static int cvs_gssapi_wrapping; #include <winsock.h> #endif -#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) +#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS4) || defined (HAVE_GSSAPI) #include <sys/socket.h> #endif @@ -61,7 +61,7 @@ static int cvs_gssapi_wrapping; # endif #endif -#ifdef HAVE_KERBEROS +#ifdef HAVE_KERBEROS4 # include <netinet/in.h> # include <krb.h> # ifndef HAVE_KRB_GET_ERR_TEXT @@ -2205,7 +2205,7 @@ serve_set (arg) #ifdef ENCRYPTION -#ifdef HAVE_KERBEROS +#ifdef HAVE_KERBEROS4 static void serve_kerberos_encrypt (arg) @@ -2221,7 +2221,7 @@ serve_kerberos_encrypt (arg) buf_from_net->memory_error); } -#endif /* HAVE_KERBEROS */ +#endif /* HAVE_KERBEROS4 */ #ifdef HAVE_GSSAPI @@ -4798,7 +4798,7 @@ struct request requests[] = 0), REQ_LINE("Set", serve_set, RQ_ROOTLESS), #ifdef ENCRYPTION -# ifdef HAVE_KERBEROS +# ifdef HAVE_KERBEROS4 REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0), # endif # ifdef HAVE_GSSAPI @@ -5256,7 +5256,7 @@ error ENOMEM Virtual memory exhausted.\n } -#if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) +#if defined (HAVE_KERBEROS4) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) static void switch_to_user PROTO((const char *)); static void @@ -5883,7 +5883,7 @@ pserver_authenticate_connection () #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */ -#ifdef HAVE_KERBEROS +#ifdef HAVE_KERBEROS4 void kserver_authenticate_connection () { @@ -5951,7 +5951,7 @@ error 0 kerberos: can't get local name: /* Switch to run as this user. */ switch_to_user (user); } -#endif /* HAVE_KERBEROS */ +#endif /* HAVE_KERBEROS4 */ #ifdef HAVE_GSSAPI @@ -6083,7 +6083,7 @@ int cvsauthenticate; #ifdef ENCRYPTION -#ifdef HAVE_KERBEROS +#ifdef HAVE_KERBEROS4 /* An encryption interface using Kerberos. This is built on top of a packetizing buffer. */ @@ -6194,7 +6194,7 @@ krb_encrypt_output (fnclosure, input, ou return 0; } -#endif /* HAVE_KERBEROS */ +#endif /* HAVE_KERBEROS4 */ #endif /* ENCRYPTION */ #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ --- ccvs/src/root.c~kerberos-client Fri May 2 15:02:15 2003 +++ ccvs-alexm/src/root.c Fri May 2 15:02:25 2003 @@ -628,7 +628,7 @@ parse_cvsroot (root_in) /* no_password already set */ break; case kserver_method: -# ifndef HAVE_KERBEROS +# ifndef HAVE_KERBEROS4 error (0, 0, "CVSROOT is set for a kerberos access method but your"); error (0, 0, "CVS executable doesn't support it."); goto error_exit; --- ccvs/src/main.c~kerberos-client Fri May 2 15:02:17 2003 +++ ccvs-alexm/src/main.c Fri May 2 15:02:39 2003 @@ -117,7 +117,7 @@ static const struct cmd { "history", "hi", "his", history, CVS_CMD_USES_WORK_DIR }, { "import", "im", "imp", import, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR | CVS_CMD_IGNORE_ADMROOT}, { "init", NULL, NULL, init, CVS_CMD_MODIFIES_REPOSITORY }, -#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT) +#if defined (HAVE_KERBEROS4) && defined (SERVER_SUPPORT) { "kserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */ #endif { "log", "lo", NULL, cvslog, CVS_CMD_USES_WORK_DIR }, @@ -208,7 +208,7 @@ static const char *const cmd_usage[] = " history Show repository access history\n", " import Import sources into CVS, using vendor branches\n", " init Create a CVS repository if it doesn't exist\n", -#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT) +#if defined (HAVE_KERBEROS4) && defined (SERVER_SUPPORT) " kserver Kerberos server mode\n", #endif " log Print out history information for files\n", @@ -702,7 +702,7 @@ cause intermittent sandbox corruption.") #ifdef SERVER_SUPPORT -# ifdef HAVE_KERBEROS +# ifdef HAVE_KERBEROS4 /* If we are invoked with a single argument "kserver", then we are running as Kerberos server as root. Do the authentication as the very first thing, to minimize the amount of time we are @@ -714,7 +714,7 @@ cause intermittent sandbox corruption.") /* Pretend we were invoked as a plain server. */ command_name = "server"; } -# endif /* HAVE_KERBEROS */ +# endif /* HAVE_KERBEROS4 */ # if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) _ --alexm