Return-Path: Date: Tue, 23 Mar 1999 23:27:59 -0700 From: Tyler Colbert X-Accept-Language: en To: "info-cvs@gnu.org" Subject: CVS on NT and GSSAPI Content-Type: text/plain; charset=us-ascii Assuming there is interest: I have successfully set up a CVS gserver under linux, then built an NT client capable of authenticating to it using kerberos5. Along the way, I had to patch CVS (sorry, all you get it a description, I havent had time to build a patch.. and its a rough description at that...:-( ) Support for the server side (Linux) went as expected... no hitches.. Support for the client side (NT) was relatively straight forward with only a few code changes (assuming that you already have GSSAPI (krb5) working under NT). Change 1: in src/server.c the first #ifdef SERVER_SUPPORT (line 19 or so) wraps some includes and global variables that are used if defined(HAVE_GSSAPI) && (defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)) later on in the file (not all on one line..). So, I broke that first #ifdef up into a few so that I could get what I need when SERVER_SUPPORT is not defined but HAVE_GSSAPI and CLIENT_SUPPORT are. fairly simple. Change 2: in server.c in gserver_authenticate_connection(), there is a call at the top of the function to gethostname(). This works fine if your host has only one name.. but my particular server has 2. and since Kerberos requires an exact match of the full principal, the authentication thought it was succeeding, but my client died a miserable death from recieving un-decryptable garbage from the server. My first solution, which should work, but didnt for me for some reason was: change the line: struct hostent *hp; into struct hostent *hp = NULL; replace the first 2 lines in the function: gethostname(hostname, sizeof hostname); hp = gethostbyname (hostname); with: struct sockaddr_in from; int fromlen; fromlen = sizeof(struct sockaddr_in); if(getsockname(STDIN_FILENO,(struct sockaddr *)&from, &fromlen) == 0){ hp = gethostbyaddr((char *)&(from.sin_addr.s_addr), fromlen, AF_INET); } if(!hp){ gethostname(hostname, sizeof hostname); hp = gethostbyname(hostname); } In this way, the destination IP of the socket (the server's IP) is attempted first, if it doesnt reverse DNS for some reason, or we arent attached to a socket, then it falls back to the old method of just asking for the hostname. I dont know how portable this is, but its probably not bad (since its similar to kerberos' kpropd). BUT, this didnt work for me since for some reason my gethostbyaddr() was unable to reverse DNS my own IP which is in my hosts file.. (argh.. anyone want to throw out a suggestion?) so I did a major klude and just checked the IP against my second IP and forced hostname to be that name when the IP matched. also, just a note, my particular gssapi returns "Miscellenious failure" when just about anything goes wrong like cvs/host@realm key doesnt exist in the keytab.. (not cvs's fault, but just incase someone wonders why it happens) my server is a Linux slakware 2.0.35 kernel my client is Win98 cvs source version 1.10.5 my cvs config.h is the standard winnt one starting with /* config.h --- configuration file for Windows NT Jim Blandy --- July 1995 */ and has the following hacks added: #define HAVE_GSSAPI 1 #define HAVE_GSSAPI_GSSAPI_H 1 #define HAVE_GSSAPI_GSSAPI_GENERIC_H 1 #define ENCRYPTION 1 sorry that I couldnt give you a patch file, but Im in a hurry... Tyler Colbert tyler-c@usa.net